//
// Created by f12160c on 2018/6/13.
//

#ifndef LEARNALGORITHM_DIRECTINSERTSORTING_HPP
#define LEARNALGORITHM_DIRECTINSERTSORTING_HPP

#include <iostream>
#include <vector>

namespace LearnAlgorithm {
    std::vector<int> DirectInsertSorting(std::vector<int>& input, std::true_type);
    std::vector<int> DirectInsertSorting(std::vector<int>& input, std::false_type);

    template <int tag_dispatcher>
    inline std::vector<int> DirectInsertSorting(std::vector<int>& v, bool choise);

    template <>
    inline std::vector<int> DirectInsertSorting<0>(std::vector<int>& v, bool choise)
    {
        std::cout << "volatile" << std::endl;
        if(choise == true) {
            return DirectInsertSorting(v, typename std::integral_constant<bool, true>::type());
        }
        else {
            return DirectInsertSorting(v, typename std::integral_constant<bool, false>::type());
        }
    }

    template <>
    inline std::vector<int> DirectInsertSorting<1>(std::vector<int>& v, bool choise)
    {
        std::cout << "const false" << std::endl;
        return DirectInsertSorting(v, typename std::integral_constant<bool, false>::type());
    }

    template <>
    inline std::vector<int> DirectInsertSorting<2>(std::vector<int>& v, bool choise)
    {
        std::cout << "const true" << std::endl;
        return DirectInsertSorting(v, typename std::integral_constant<bool, true>::type());;
    }

#define DirectInsertSorting(input, flag) DirectInsertSorting<__builtin_constant_p(flag)?(flag?2:1):0>(input, flag)

}

#endif //LEARNALGORITHM_DIRECTINSERTSORTING_HPP
